/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       material_array.h

	$Header: /game/material_array.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef MATERIAL_ARRAY_H_INCLUDED
#define MATERIAL_ARRAY_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <iosfwd>

#include "int_array.h"
#include "material_amount.h"

class t_material_array : public t_int_array<k_material_count>
{
public:
	bool read( std::streambuf& buffer );
	bool write( std::streambuf& buffer ) const;

	t_material_array&	operator+=( t_material_array const& arg );
	t_material_array&	operator+=( int arg );
	t_material_array&	operator += ( t_material_amount const& amount );
	t_material_array&	operator -= ( t_material_amount const& amount );
	t_material_array&	operator-=( t_material_array const& arg );
	t_material_array&	operator-=( int arg );

	bool operator <= (t_material_array const& arg) const;
	bool operator <  (t_material_array const& arg) const;
	bool operator >  (t_material_array const& arg) const;
	bool operator >= (t_material_array const& arg) const;
	int  operator /  (const t_material_array& arg ) const;
};

// ----------------------------------------------------------
// inlines for material array
// ----------------------------------------------------------
inline t_material_array& t_material_array::operator+=( t_material_array const& arg )
{
	t_int_array<k_material_count>::operator+=( arg );
	return *this;
}

inline t_material_array& t_material_array::operator+=( int arg )
{
	t_int_array<k_material_count>::operator+=( arg );
	return *this;
}

inline t_material_array& t_material_array::operator-=( t_material_array const& arg )
{
	t_int_array<k_material_count>::operator-=( arg );
	return *this;
}

inline t_material_array& t_material_array::operator-=( int arg )
{
	t_int_array<k_material_count>::operator-=( arg );
	return *this;
}

inline bool t_material_array::operator < (t_material_array const& arg) const
{
	int const* left  = m_data;
	int const* right = arg.get();
	int        count = k_size;

	while (count--)
		if (*left++ < *right++)
			return true;
	return false;
}

inline bool t_material_array::operator <= (t_material_array const& arg) const
{
	int const* left  = m_data;
	int const* right = arg.get();
	int        count = k_size;

	while (count--)
		if (*left++ <= *right++)
			return true;
	return false;
}

inline bool t_material_array::operator > (t_material_array const& arg) const
{
	return !(operator <= ( arg ));
}

inline bool t_material_array::operator >= (t_material_array const& arg) const
{
	return !(operator < (arg));
}

inline int t_material_array::operator /  (const t_material_array& arg ) const
{
	int const* left  = m_data;
	int const* right = arg.get();
	int        count = k_size;

	int result = 1000000000;
	int quotient;

	while (count--)
	{
		if (*right > 0)
		{
			quotient = *left / *right;
			if (quotient < result)
				result = quotient;
			if (result == 0)
				return 0;
		}
		left++;
		right++;
	}
	return result;
}

inline t_material_array& t_material_array::operator += ( t_material_amount const& amount )
{
	m_data[amount.material] += amount.amount;
	return *this;
}

inline t_material_array& t_material_array::operator -= ( t_material_amount const& amount )
{
	m_data[amount.material] += amount.amount;
	return *this;
}

// ---------------------------------------------------------------
// associated binary functions
// ---------------------------------------------------------------
inline t_material_array operator+( t_material_array left, t_material_array const& right )
{
	left += right;
	return left;
}

inline t_material_array operator+( t_material_array left, int right )
{
	left += right;
	return left;
}

inline t_material_array operator+( int left, t_material_array right )
{
	right += left;
	return right;
}

inline t_material_array operator+( t_material_array left, t_material_amount const& right )
{
	left += right;
	return left;
}

inline t_material_array operator+( t_material_amount const& left, t_material_array right )
{
	right += left;
	return right;
}

inline t_material_array operator-( t_material_array left, t_material_array const& right )
{
	left -= right;
	return left;
}

inline t_material_array operator-( t_material_array left, int right )
{
	left -= right;
	return left;
}

inline t_material_array operator-( t_material_array left, t_material_amount const& right )
{
	left -= right;
	return left;
}

inline t_material_array operator*( t_material_array left, int right )
{
	left *= right;
	return left;
}

inline t_material_array operator*( int left, t_material_array right )
{
	right *= left;
	return right;
}

inline t_material_array operator/( t_material_array left, int right )
{
	left /= right;
	return left;
}

#endif // MATERIAL_ARRAY_H_INCLUDED